package com.zy.facepp.service;

import java.util.LinkedHashMap;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import com.alibaba.fastjson.JSONObject;
import com.zy.facepp.bean.FaceCompareParams;
import com.zy.facepp.constant.FaceppConstant;

/**
 * Face++ 人脸识别Service
 *
 * @author zhanghengchang
 * @date 2018/3/8
 */
@Service
public class FacePlusPlusFaceService extends FacePlusPlusService {

    private static Logger logger = LoggerFactory.getLogger(FacePlusPlusFaceService.class);

    /**
     * 人脸比对
     *
     * @param params face_token1 第一个人脸标识 <br/>
     *        face_token (四选一) <br/>
     *        image_url1 第一张图片的 URL <br/>
     *        image_file1 第一张图片，二进制文件 <br/>
     *        image_base64_1 第一张图片base64编码的二进制图片数据 <br/>
     *        face_token2 第二个人脸标识 <br/>
     *        face_token (四选一) <br/>
     *        image_url2 第二张图片的 <br/>
     *        URL image_file2 第二张图片，二进制文件 <br/>
     *        image_base64_2 第二张图片base64编码的二进制图片数据
     * @return 两张人脸比对结果
     */
    public JSONObject faceCompare(FaceCompareParams params) {
        JSONObject result = faceComparePost(faceppConfig.getFaceCompareUrl(), params);

        writeReqLog(FaceppConstant.CONST_TYPE_COMPARE, params, result);
        editResponse(FaceppConstant.CONST_TYPE_COMPARE, params, result);
        createFinalResult(result);

        return result;
    }

    /**
     * 调用人脸比对接口
     *
     * @param apiUrl API URL
     * @param params 参数
     * @return 人脸比对结果
     */
    private JSONObject faceComparePost(String apiUrl, FaceCompareParams params) {
        MultiValueMap<String, Object> mvMap = new LinkedMultiValueMap<String, Object>();
        mvMap.add(FaceppConstant.KEY_FOR_APIKEY, faceppConfig.getApiKey());
        mvMap.add(FaceppConstant.KEY_FOR_APISECRET, faceppConfig.getApiSecret());

        if (StringUtils.isNotEmpty(params.getFaceToken1())) {
            mvMap.add(FaceppConstant.KEY_FOR_FACE_TOKEN1, params.getFaceToken1());
        } else if (StringUtils.isNotEmpty(params.getImageUrl1())) {
            mvMap.add(FaceppConstant.KEY_FOR_IMAGE_URL1, params.getImageUrl1());
        } else if (params.getImageFile1() != null) {
            mvMap.add(FaceppConstant.KEY_FOR_IMAGE_FILE1, new FileSystemResource(params.getImageFile1()));
        } else if (StringUtils.isNotEmpty(params.getImageBase641())) {
            mvMap.add(FaceppConstant.KEY_FOR_IMAGE_BASE64_1, new FileSystemResource(params.getImageBase641()));
        }

        if (StringUtils.isNotEmpty(params.getFaceToken2())) {
            mvMap.add(FaceppConstant.KEY_FOR_FACE_TOKEN2, params.getFaceToken2());
        } else if (StringUtils.isNotEmpty(params.getImageUrl2())) {
            mvMap.add(FaceppConstant.KEY_FOR_IMAGE_URL2, params.getImageUrl2());
        } else if (params.getImageFile2() != null) {
            mvMap.add(FaceppConstant.KEY_FOR_IMAGE_FILE2, new FileSystemResource(params.getImageFile2()));
        } else if (StringUtils.isNotEmpty(params.getImageBase642())) {
            mvMap.add(FaceppConstant.KEY_FOR_IMAGE_BASE64_2, new FileSystemResource(params.getImageBase642()));
        }

        return postTo(apiUrl, mvMap);
    }

    /**
     * 根据API返回结果，判断最终比对结果。<br/>
     * same_person: N: 不是同一个人 Y:是同一个人 U:无法判断是否是同一个人
     *
     * @param result API返回结果
     * @return 最终结果
     */
    private JSONObject createFinalResult(JSONObject result) {
        if ((boolean)result.get(FaceppConstant.CONST_RESULT_SUCCESS)) {
            Double confidence = (Double)result.get(FaceppConstant.KEY_FOR_CONFIDENCE);
            LinkedHashMap<String, Double> thresholds = (LinkedHashMap)result.get(FaceppConstant.KEY_FOR_THRESHOLDS);
            Double t1e3 = thresholds.get(FaceppConstant.KEY_FOR_THRESHOLD_1E3);
            Double t1e5 = thresholds.get(FaceppConstant.KEY_FOR_THRESHOLD_1E5);
            if (confidence.compareTo(t1e3) <= 0) {
                result.put(FaceppConstant.CONST_COMPARE_SAME_PERSON, FaceppConstant.CONST_COMPARE_SAME_PERSON_N);
            } else if (confidence.compareTo(t1e5) >= 0) {
                result.put(FaceppConstant.CONST_COMPARE_SAME_PERSON, FaceppConstant.CONST_COMPARE_SAME_PERSON_Y);
            } else {
                result.put(FaceppConstant.CONST_COMPARE_SAME_PERSON, FaceppConstant.CONST_COMPARE_SAME_PERSON_U);
            }
        } else {
            result.put(FaceppConstant.CONST_COMPARE_SAME_PERSON, FaceppConstant.CONST_COMPARE_SAME_PERSON_N);
        }
        return result;
    }

}
